﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ARR.Entities.ComponentModel;
using ARR.Shared;
using System.Reflection;

namespace ARR.Entities.Validation.Common
{
    [Serializable]
    public class DateRange : ValidationBase
    {
        bool includeLimits;
        DateTime? max;
        DateTime? min;

        public DateRange(string propertyName, DateTime? min, DateTime? max, bool includeLimits, string displayName = null) : base(propertyName, null)
        {
            string fieldName = displayName == null ? propertyName : displayName;

            string dateFormat = Constants.StringFormats.DateShortMonth;

            if (max.HasValue && min.HasValue)
            {
                base.ErrorMessage = string.Format(Errors.RangeValidation, fieldName, min.Value.ToString(dateFormat), max.Value.ToString(dateFormat));
            }
            else
            {
                if (min.HasValue)
                {
                    string message = includeLimits ? Errors.GreaterOrEqualThanValidation : Errors.GreaterThanValidation;
                    base.ErrorMessage = string.Format(message, fieldName, min.Value.ToString(dateFormat));
                }

                if (max.HasValue)
                {
                    string message = includeLimits ? Errors.LessOrEqualThanValidation : Errors.LessThanValidation;
                    base.ErrorMessage = string.Format(message, fieldName, max.Value.ToString(dateFormat));
                }
            }

            this.max = max;
            this.min = min;
            this.includeLimits = includeLimits;
        }

        public override bool Validate(ValidatableEntity entity)
        {
            PropertyInfo pi = entity.GetType().GetProperty(base.PropertyName);
            object value = pi.GetValue(entity, null);

            if (value is IComparable && value != null)
            {
                DateTime dateValue;
                if (DateTime.TryParse(value.ToString(), out dateValue))
                {
                    if (max.HasValue && min.HasValue)
                    {
                        return includeLimits ? dateValue.Date <= max.Value.Date && dateValue.Date >= min.Value.Date : dateValue.Date < max.Value.Date && dateValue.Date > min.Value.Date;
                    }

                    if (min.HasValue)
                    {
                        return includeLimits ? dateValue.Date >= min.Value.Date : dateValue.Date > min.Value.Date;
                    }


                    if (max.HasValue)
                    {
                        return includeLimits ? dateValue.Date <= max.Value.Date : dateValue.Date < max.Value.Date;
                    }
                }
            }

            return false;
        }
    }
}
